#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <queue>
#include <condition_variable>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>

// 简化的扫描结果结构
struct SimpleFileInfo {
    std::string filePath;
    size_t fileSize;
    
    SimpleFileInfo(const std::string& path, size_t size) 
        : filePath(path), fileSize(size) {}
};

// 简化的文件扫描器类
class SimpleFileScanner {
private:
    std::vector<std::thread> workers;
    std::queue<std::string> taskQueue;
    std::mutex queueMutex;
    std::condition_variable condition;
    std::atomic<bool> shouldStop;
    std::atomic<bool> scanning;
    
    std::vector<SimpleFileInfo> results;
    std::mutex resultsMutex;
    
    std::atomic<size_t> totalFiles;
    std::atomic<size_t> totalBytes;
    
    static const int THREAD_COUNT = 4;

public:
    SimpleFileScanner() : shouldStop(false), scanning(false), totalFiles(0), totalBytes(0) {
        // 创建工作线程
        for (int i = 0; i < THREAD_COUNT; ++i) {
            workers.emplace_back(&SimpleFileScanner::workerFunction, this);
        }
    }
    
    ~SimpleFileScanner() {
        stop();
        shouldStop = true;
        condition.notify_all();
        
        for (auto& worker : workers) {
            if (worker.joinable()) {
                worker.join();
            }
        }
    }
    
    bool start(const std::string& path) {
        if (scanning.load()) {
            return false;
        }
        
        // 检查路径是否存在
        struct stat statBuf;
        if (stat(path.c_str(), &statBuf) != 0 || !S_ISDIR(statBuf.st_mode)) {
            std::cerr << "错误: 路径不存在或不是目录: " << path << std::endl;
            return false;
        }
        
        // 重置状态
        shouldStop = false;
        scanning = true;
        totalFiles = 0;
        totalBytes = 0;
        
        {
            std::lock_guard<std::mutex> lock(resultsMutex);
            results.clear();
        }
        
        // 添加初始任务
        {
            std::lock_guard<std::mutex> lock(queueMutex);
            taskQueue.push(path);
        }
        condition.notify_one();
        
        std::cout << "开始扫描: " << path << std::endl;
        return true;
    }
    
    void stop() {
        scanning = false;
        std::cout << "停止扫描" << std::endl;
    }
    
    bool isScanning() const {
        return scanning.load();
    }
    
    size_t getTotalFiles() const {
        return totalFiles.load();
    }
    
    size_t getTotalBytes() const {
        return totalBytes.load();
    }
    
    std::vector<SimpleFileInfo> getResults() const {
        std::lock_guard<std::mutex> lock(resultsMutex);
        return results;
    }

private:
    void workerFunction() {
        while (!shouldStop.load()) {
            std::string dirPath;
            
            // 获取任务
            {
                std::unique_lock<std::mutex> lock(queueMutex);
                condition.wait(lock, [this] { 
                    return !taskQueue.empty() || shouldStop.load(); 
                });
                
                if (shouldStop.load()) {
                    break;
                }
                
                if (taskQueue.empty()) {
                    continue;
                }
                
                dirPath = taskQueue.front();
                taskQueue.pop();
            }
            
            // 扫描目录
            scanDirectory(dirPath);
        }
    }
    
    void scanDirectory(const std::string& dirPath) {
        if (!scanning.load() || shouldStop.load()) {
            return;
        }
        
        DIR* dir = opendir(dirPath.c_str());
        if (!dir) {
            return;
        }
        
        struct dirent* entry;
        while ((entry = readdir(dir)) != nullptr && scanning.load() && !shouldStop.load()) {
            std::string name = entry->d_name;
            if (name == "." || name == "..") {
                continue;
            }
            
            std::string fullPath = dirPath + "/" + name;
            
            struct stat fileStat;
            if (stat(fullPath.c_str(), &fileStat) == 0) {
                if (S_ISDIR(fileStat.st_mode)) {
                    // 子目录，添加到任务队列
                    std::lock_guard<std::mutex> lock(queueMutex);
                    taskQueue.push(fullPath);
                    condition.notify_one();
                } else if (S_ISREG(fileStat.st_mode)) {
                    // 普通文件
                    size_t fileSize = static_cast<size_t>(fileStat.st_size);
                    
                    {
                        std::lock_guard<std::mutex> lock(resultsMutex);
                        results.emplace_back(fullPath, fileSize);
                    }
                    
                    totalFiles++;
                    totalBytes += fileSize;
                    
                    // 每100个文件输出一次进度
                    if (totalFiles % 100 == 0) {
                        std::cout << "已扫描 " << totalFiles << " 个文件, "
                                  << "总大小: " << (totalBytes / 1024 / 1024) << " MB" << std::endl;
                    }
                }
            }
        }
        
        closedir(dir);
    }
};

// 测试程序
int main(int argc, char* argv[]) {
    std::cout << "=== 简化版文件扫描器测试 ===" << std::endl;
    
    std::string scanPath = "/home/lyt";
    if (argc > 1) {
        scanPath = argv[1];
    }
    
    std::cout << "扫描路径: " << scanPath << std::endl;
    
    SimpleFileScanner scanner;
    
    if (!scanner.start(scanPath)) {
        std::cerr << "启动扫描失败" << std::endl;
        return 1;
    }
    
    // 监控进度
    auto startTime = std::chrono::steady_clock::now();
    while (scanner.isScanning()) {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        
        auto currentTime = std::chrono::steady_clock::now();
        auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(currentTime - startTime).count();
        
        std::cout << "进度: " << scanner.getTotalFiles() << " 文件, "
                  << (scanner.getTotalBytes() / 1024 / 1024) << " MB, "
                  << elapsed << " 秒" << std::endl;
        
        // 10秒后停止测试
        if (elapsed > 10) {
            std::cout << "测试时间到，停止扫描..." << std::endl;
            scanner.stop();
            break;
        }
    }
    
    // 等待扫描完成
    std::this_thread::sleep_for(std::chrono::seconds(1));
    
    // 显示结果
    auto results = scanner.getResults();
    std::cout << "\n=== 扫描结果 ===" << std::endl;
    std::cout << "总文件数: " << scanner.getTotalFiles() << std::endl;
    std::cout << "总大小: " << (scanner.getTotalBytes() / 1024 / 1024) << " MB" << std::endl;
    
    std::cout << "\n前10个文件:" << std::endl;
    for (size_t i = 0; i < std::min(results.size(), size_t(10)); ++i) {
        std::cout << "  " << results[i].filePath 
                  << " (" << results[i].fileSize << " bytes)" << std::endl;
    }
    
    std::cout << "\n测试完成!" << std::endl;
    return 0;
}